
////////////////////////////////////////////////////////////////////////////////
//
// Parts.java
//
// Copyright © (C) 2010
// 
// Emory Hughes Merryman, III
// emory.merryman@gmail.com
// 
// All Rights Reserved
// 
// This file is part of Interworks.
// 
// Interworks is free software: you can 
// redistribute it and/or modify it under 
// the terms of the GNU General Public 
// License as published by the Free 
// Software Foundation, either version 3 
// of the License, or (at your option) any 
// later version.
// 
// This program is distributed in the hope 
// that it will be useful, but WITHOUT 
// ANY WARRANTY; without even the 
// implied warranty of MERCHANTABILITY 
// or FITNESS FOR A PARTICULAR 
// PURPOSE.  See the GNU General Public 
// License for more details.
//
// You should have received a copy of the 
// GNU General Public License along with 
// this program.  If not, see 
// <http://www.gnu.org/licenses/>.
////////////////////////////////////////////////////////////////////////////////

package
    com . superiorglobalbusiness . cB7zEmeT ;

import java . util . Map ;
import java . util . HashMap ;

import java . io . File ;
import javax . xml . parsers . SAXParserFactory ;
import org . xml . sax . helpers . DefaultHandler ;
import org . xml . sax . Attributes ;

import java . util . concurrent . atomic . AtomicInteger ;
import java . util . concurrent . atomic . AtomicReference ;
import java . util . List ;
import java . util . ArrayList ;

import org . docx4j . openpackaging . packages . PresentationMLPackage ;
import org . docx4j . openpackaging . parts . PartName ;
import org . docx4j . openpackaging . parts . Part ;
import org . docx4j . openpackaging . parts . PresentationML . SlidePart ;

import org . docx4j . openpackaging . exceptions . InvalidFormatException ;
import org . docx4j . openpackaging . exceptions . Docx4JException ;

import org . pptx4j . pml . * ;
import org . docx4j . openpackaging . parts . relationships . * ;

import org . pptx4j . pml . * ;
import org . docx4j . dml . * ;

import org . docx4j . dml . STLineCap ;
import org . docx4j . dml . STPresetColorVal ;
import org . docx4j . dml . STShapeType ;
import org . docx4j . dml . STTextWrappingType ;
import org . docx4j . dml . STLineEndType ;

import org.pptx4j.jaxb.Context;
import org.docx4j.XmlUtils;


final class Parts
{
    private static final org . pptx4j . pml . ObjectFactory PML_FACTORY = new org . pptx4j . pml . ObjectFactory ( ) ;

    private static final org . docx4j . dml . ObjectFactory DML_FACTORY = new org . docx4j . dml . ObjectFactory ( ) ;

    private static long BLOCK_WIDTH = 4210957 / 3 ;

    private static long BLOCK_HEIGHT = 410641 ;

    private static final long ROW_HEIGHT = 3 * BLOCK_HEIGHT ;

    private static final long COL_WIDTH = BLOCK_WIDTH * 3 / 2 ;

    private Parts ( )
    {
	super ( ) ;
    }

    public static void main ( String [ ] args )
    {
	if ( args . length != 2 )
	    {
		System . err . println ( "Usage:  java Main {inputFile} {outputFile}" ) ;
		System . exit ( 0 ) ;
	    }
	final Map < String , STShapeType > shapes = new HashMap < String , STShapeType > ( ) ;
	shapes . put ( "triangle" , STShapeType . TRIANGLE ) ;
	shapes . put ( "ellipse" , STShapeType . ELLIPSE ) ;
	shapes . put ( "roundRect" , STShapeType . ROUND_1_RECT ) ;
	shapes . put ( "rect" , STShapeType . RECT ) ;
	shapes . put ( "trapezoid" , STShapeType . TRAPEZOID ) ;
	shapes . put ( "parallelogram" , STShapeType . PARALLELOGRAM ) ;
	shapes . put ( "line" , STShapeType . LINE ) ;
	final Map < String , STPresetColorVal > colors = new HashMap < String , STPresetColorVal > ( ) ;
	colors . put ( "red" , STPresetColorVal . RED ) ;
	colors . put ( "green" , STPresetColorVal . GREEN ) ;
	colors . put ( "blue" , STPresetColorVal . BLUE ) ;
	colors . put ( "yellow" , STPresetColorVal . YELLOW ) ;
	colors . put ( "white" , STPresetColorVal . WHITE ) ;
	colors . put ( "black" , STPresetColorVal . BLACK ) ;
	colors . put ( "gray" , STPresetColorVal . GRAY ) ;
	colors . put ( "purple" , STPresetColorVal . PURPLE ) ;
	colors . put ( "orange" , STPresetColorVal . ORANGE ) ;
	final AtomicReference < PresentationMLPackage > presentationMLPackage = new AtomicReference < PresentationMLPackage > ( ) ;
	final AtomicInteger slideCounter = new AtomicInteger ( ) ;
	final AtomicReference < List < Object > > spOrGrpSpOrGraphicFrame = new AtomicReference < List < Object > > ( ) ;
	final AtomicReference < List < Runnable > > slideRunnables = new AtomicReference < List < Runnable > > ( ) ;
	final AtomicReference < Map < String , Shape > > sp = new AtomicReference < Map < String , Shape > > ( ) ;
	final File output = new File ( args [ 1 ] ) ;
	DefaultHandler defaultHandler = new DefaultHandler ( )
	    {
		public void startElement ( String uri , String localName , String qName , Attributes attr )
		{
		    if ( "presentation" . equals ( qName ) )
			{
			    try
				{
				    assert presentationMLPackage . compareAndSet ( null , PresentationMLPackage . createPackage ( ) ) ;
				}
			    catch ( InvalidFormatException cause )
				{
				    assert false : cause ;
				}
			    slideCounter . set ( 0 ) ;
			}
		    else if ( "slide" . equals ( qName ) )
			{
			    slideCounter . getAndIncrement ( ) ;
			    StringBuilder sb = new StringBuilder ( ) ;
			    sb . append ( "/ppt/slides/slide" ) ;
			    sb . append ( slideCounter ) ;
			    sb . append ( ".xml" ) ;
			    try
				{
				    PartName partName = new PartName ( sb . toString ( ) ) ;
				    Part part = presentationMLPackage . get ( ) . getParts ( ) . get ( partName ) ;
				    if ( part == null )
					{
					    part = new SlidePart ( partName ) ;
					    presentationMLPackage . get ( ) . getParts ( ) . put ( part ) ;
					}
				    assert spOrGrpSpOrGraphicFrame . compareAndSet ( null , ( ( SlidePart ) ( part ) ) . getJaxbElement ( ) . getCSld ( ) . getSpTree ( ) . getSpOrGrpSpOrGraphicFrame ( ) ) ;
				}
			    catch ( InvalidFormatException cause )
				{
				    assert false : cause ;
				}
			    assert slideRunnables . compareAndSet ( null , new ArrayList < Runnable > ( ) ) ;
			}
		    else if ( "tree" . equals ( qName ) )
			{
			}
		    else if ( "top" . equals ( qName ) )
			{
			    final String id = attr . getValue ( "id" ) ;
			    Runnable r = new Runnable ( )
				{
				    public void run ( )
				    {
					
				    }
				} ;
			    slideRunnables . get ( ) . add ( r ) ;
			}
		    else if ( "child" . equals ( qName ) )
			{
			}
		    else if ( "shape" . equals ( qName ) )
			{
			    
			}
		    else if ( "text" . equals ( qName ) )
			{
			}
		    else
			{
			}
		}

		public void stopElement ( String uri , String localName , String qName )
		{
		    if ( "presentation" . equals ( qName ) )
			{
			    try
				{
				    presentationMLPackage . get ( ) . save ( output ) ;
				}
			    catch ( Docx4JException cause )
				{
				    System . err . println ( "There was a problem saving." ) ;
				}
			    presentationMLPackage . set ( null ) ;
			}
		    else if ( "slide" . equals ( qName ) )
			{
			    spOrGrpSpOrGraphicFrame . set ( null ) ;
			    slideRunnables . set ( null ) ;
			}
		    else if ( "tree" . equals ( qName ) )
			{
			}
		    else if ( "top" . equals ( qName ) )
			{
			}
		    else if ( "child" . equals ( qName ) )
			{
			}
		    else if ( "shape" . equals ( qName ) )
			{
			}
		    else if ( "text" . equals ( qName ) )
			{
			}
		    else
			{
			}
		}
	    } ;
	// SAXParserFactory . newInstance ( ) . newSAXParser ( ) . parse ( new File ( args [ 0 ] ) , defaultHandler ) ;
    }

    public static final void oldmain ( final String [ ] args ) throws Exception
    {
	/*
	final java . io . BufferedReader reader = new java . io . BufferedReader ( new java . io . InputStreamReader ( Parts . class . getResourceAsStream ( "/com/superiorglobalbusiness/cB7zEmeT/Director.xml" ) ) ) ;
	final java . io . StringWriter writer = new java . io . StringWriter ( ) ;
	for ( java . lang . String line = reader . readLine ( ) ; line != null ; line = reader . readLine ( ) )
	    {
		writer . append ( line ) ;
	    }
	reader . close ( ) ;
	writer . close ( ) ;
	final java . lang . String xml = writer . toString ( ) ;
	System . out . println ( xml ) ;
	if ( xml == null ) { System . exit ( 0 ) ; }
	*/

	final PresentationMLPackage w = PresentationMLPackage . createPackage ( ) ;
	final Part s1 = w . getParts ( ) . get ( new PartName ( "/ppt/slides/slide1.xml" ) ) ;
	final SlidePart sp1 = ( SlidePart ) ( s1 ) ;
	/*
	final Shape shape = ( ( Shape ) XmlUtils . unmarshalString ( xml , Context . jcPML ) );
	*/

	exp ( sp1 ) ;


	File f = File . createTempFile ( "Parts." , ".pptx" ) ;
	w . save ( f ) ;
	Process proc = Runtime . getRuntime ( ) . exec ( "ooimpress " + f ) ;
	proc . waitFor ( ) ;
    }

    private static final void exp ( final SlidePart sp1 )
    {
	final AtomicReference < CTConnectionSite > alpha = new AtomicReference < CTConnectionSite > ( ) ;
	final AtomicReference < CTConnectionSite > beta = new AtomicReference < CTConnectionSite > ( ) ;
	block ( sp1 , 100 , 83822 , 2 * ROW_HEIGHT , STShapeType . IRREGULAR_SEAL_1 , STPresetColorVal . CADET_BLUE , "Top" , new AtomicReference < CTConnectionSite > ( ) , alpha  ) ;
	block ( sp1 , 200 , 83822 , 3 * ROW_HEIGHT , STShapeType . IRREGULAR_SEAL_1 , STPresetColorVal . CADET_BLUE , "Bottom" , beta , new AtomicReference < CTConnectionSite > ( )  ) ;
	final CxnSp connection = PML_FACTORY . createCxnSp ( ) ;
	connection . setNvCxnSpPr ( PML_FACTORY . createCxnSpNvCxnSpPr ( ) ) ;
	connection . getNvCxnSpPr ( ) . setCNvCxnSpPr ( DML_FACTORY . createCTNonVisualConnectorProperties ( ) ) ;
	connection . getNvCxnSpPr ( ) . getCNvCxnSpPr ( ) . setStCxn ( DML_FACTORY . createCTConnection ( ) ) ;
	connection . getNvCxnSpPr ( ) . getCNvCxnSpPr ( ) . getStCxn ( ) . setId ( 100 ) ;
	connection . getNvCxnSpPr ( ) . getCNvCxnSpPr ( ) . getStCxn ( ) . setIdx ( 1 ) ;
	connection . getNvCxnSpPr ( ) . getCNvCxnSpPr ( ) . setEndCxn ( DML_FACTORY . createCTConnection ( ) ) ;
	connection . getNvCxnSpPr ( ) . getCNvCxnSpPr ( ) . getEndCxn ( ) . setId ( 200 ) ;
	connection . getNvCxnSpPr ( ) . getCNvCxnSpPr ( ) . getEndCxn ( ) . setIdx ( 1 ) ;
	connection . setSpPr ( DML_FACTORY . createCTShapeProperties ( ) ) ;
	connection . getSpPr ( ) . setPrstGeom ( DML_FACTORY . createCTPresetGeometry2D ( ) ) ;
	connection . getSpPr ( ) . getPrstGeom ( ) . setPrst ( STShapeType . STRAIGHT_CONNECTOR_1 ) ;
	connection . getSpPr ( ) . getPrstGeom ( ) . setAvLst ( DML_FACTORY . createCTGeomGuideList ( ) ) ;
	connection . getSpPr ( ) . setCustGeom ( DML_FACTORY . createCTCustomGeometry2D ( ) ) ;
	connection . getSpPr ( ) . getCustGeom ( ) . setCxnLst ( DML_FACTORY . createCTConnectionSiteList ( ) ) ;
	connection . getSpPr ( ) . getCustGeom ( ) . getCxnLst ( ) . getCxn ( ) . add ( alpha . get ( ) ) ;
	connection . getSpPr ( ) . getCustGeom ( ) . getCxnLst ( ) . getCxn ( ) . add ( beta . get ( ) ) ;
	line ( connection . getSpPr ( ) , STPresetColorVal . CADET_BLUE ) ;
	connection . getSpPr ( ) . getLn ( ) . setTailEnd ( DML_FACTORY . createCTLineEndProperties ( ) ) ;
	connection . getSpPr ( ) . getLn ( ) . getTailEnd ( ) . setType ( STLineEndType . ARROW ) ;
	connection . setStyle ( DML_FACTORY . createCTShapeStyle ( ) ) ;
	connection . getStyle ( ) . setLnRef ( DML_FACTORY . createCTStyleMatrixReference ( ) ) ;
	connection . getStyle ( ) . getLnRef ( ) . setPrstClr ( DML_FACTORY . createCTPresetColor ( ) ) ;
	connection . getStyle ( ) . getLnRef ( ) . getPrstClr ( ) . setVal ( STPresetColorVal . CADET_BLUE ) ;
	sp1 . getJaxbElement ( ) . getCSld ( ) . getSpTree ( ) . getSpOrGrpSpOrGraphicFrame ( ) . add ( connection ) ;
    }

    private static final void block
	(
	 final SlidePart sld ,
	 final int id ,
	 final long x ,
	 final long y ,
	 final STShapeType shapeType ,
	 final STPresetColorVal color ,
	 final String text ,
	 final AtomicReference < CTConnectionSite > topConnection ,
	 final AtomicReference < CTConnectionSite > bottomConnection
	 )
    {
	final Shape shape = PML_FACTORY . createShape ( ) ;
	shape . setNvSpPr ( PML_FACTORY . createShapeNvSpPr ( ) ) ;
	shape . getNvSpPr ( ) . setCNvPr ( DML_FACTORY . createCTNonVisualDrawingProps ( ) ) ;
	shape . getNvSpPr ( ) . getCNvPr ( ) . setId ( id ) ;
	//	shape . getNvSpPr ( ) . getCNvPr ( ) . setName ( "Text Box 7" ) ;
	shape . setSpPr ( DML_FACTORY . createCTShapeProperties ( ) ) ;
	shape . getSpPr ( ) . setXfrm ( DML_FACTORY . createCTTransform2D ( ) ) ;
	shape . getSpPr ( ) . getXfrm ( ) . setOff ( DML_FACTORY . createCTPoint2D ( ) ) ;
	shape . getSpPr ( ) . getXfrm ( ) . getOff ( ) . setX ( x ) ;
	shape . getSpPr ( ) . getXfrm ( ) . getOff ( ) . setY ( y ) ;
	shape . getSpPr ( ) . getXfrm ( ) . setExt ( DML_FACTORY . createCTPositiveSize2D ( ) ) ;
	shape . getSpPr ( ) . getXfrm ( ) . getExt ( ) . setCx ( BLOCK_WIDTH ) ;
	shape . getSpPr ( ) . getXfrm ( ) . getExt ( ) . setCy ( BLOCK_HEIGHT ) ;
	line ( shape . getSpPr ( ) , color ) ;
	shape . getSpPr ( ) . setPrstGeom ( DML_FACTORY . createCTPresetGeometry2D ( ) ) ;
	shape . getSpPr ( ) . getPrstGeom ( ) . setPrst ( shapeType ) ;
	shape . getSpPr ( ) . setCustGeom ( DML_FACTORY . createCTCustomGeometry2D ( ) ) ;
	shape . getSpPr ( ) . getCustGeom ( ) . setCxnLst ( DML_FACTORY . createCTConnectionSiteList ( ) ) ;
	connectionPoint ( shape . getSpPr ( ) . getCustGeom ( ) , topConnection , true ) ;
	connectionPoint ( shape . getSpPr ( ) . getCustGeom ( ) , bottomConnection , false) ;

	for ( int i = 0 ; i < shape . getSpPr ( ) . getCustGeom ( ) . getCxnLst ( ) . getCxn ( ) . size ( ) ; i ++ )
	    {
		System . out . println ( i + "\t" + shape . getSpPr ( ) . getCustGeom ( ) . getCxnLst ( ) . getCxn ( ) . get ( i ) . getAng ( ) + "\t" + shape . getSpPr ( ) . getCustGeom ( ) . getCxnLst ( ) . getCxn ( ) . get ( i ) . getPos ( ) . getX ( ) + "\t" + shape . getSpPr ( ) . getCustGeom ( ) . getCxnLst ( ) . getCxn ( ) . get ( i ) . getPos ( ) . getY ( ) ) ;
	    }


	shape . getSpPr ( ) . setNoFill ( DML_FACTORY . createCTNoFillProperties ( ) ) ;
	shape . setTxBody ( DML_FACTORY . createCTTextBody ( ) ) ;
	shape . getTxBody ( ) . setBodyPr ( DML_FACTORY . createCTTextBodyProperties ( ) ) ;
	shape . getTxBody ( ) . getBodyPr ( ) . setWrap ( STTextWrappingType . SQUARE ) ;
	shape . getTxBody ( ) . getBodyPr ( ) . setLIns ( 101870 ) ;
	shape . getTxBody ( ) . getBodyPr ( ) . setTIns ( 50935 ) ;
	shape . getTxBody ( ) . getBodyPr ( ) . setRIns ( 101870 ) ;
	shape . getTxBody ( ) . getBodyPr ( ) . setBIns ( 50935 ) ;
	shape . getTxBody ( ) . getBodyPr ( ) . setRtlCol ( false ) ;
	shape . getTxBody ( ) . getBodyPr ( ) . setSpAutoFit ( DML_FACTORY . createCTTextShapeAutofit ( ) ) ;
	shape . getTxBody ( ) . setLstStyle ( DML_FACTORY . createCTTextListStyle ( ) ) ;
	final CTTextParagraph paragraph = DML_FACTORY . createCTTextParagraph ( ) ;
	final CTRegularTextRun run = DML_FACTORY . createCTRegularTextRun ( ) ;
	run . setRPr ( DML_FACTORY . createCTTextCharacterProperties ( ) ) ;
	run . getRPr ( ) . setLang ( "en-US" ) ;
	run . getRPr ( ) . setSz ( 900 ) ;
	run . getRPr ( ) . setDirty ( false ) ;
	run . getRPr ( ) . setSmtClean ( false ) ;
	run . getRPr ( ) . setLatin ( DML_FACTORY .createTextFont ( ) ) ;
	run . getRPr ( ) . getLatin ( ) . setTypeface ( "Aria" ) ;
	run . getRPr ( ) . setCs ( DML_FACTORY . createTextFont ( ) ) ;
	run . getRPr ( ) . getCs ( ) . setTypeface ( "Aria" ) ;
	run . setT ( text ) ;
	paragraph . getEGTextRun ( ) . add ( run ) ;
	shape . getTxBody ( ) . getP ( ) . add ( paragraph ) ;
	sld . getJaxbElement ( ) . getCSld ( ) . getSpTree ( ) . getSpOrGrpSpOrGraphicFrame ( ) . add ( shape ) ;
    }

    private static final void connectionPoint
	(
	 final CTCustomGeometry2D customGeom ,
	 final AtomicReference < CTConnectionSite > connection ,
	 final boolean isTop
	 )
    {
	connection . set ( DML_FACTORY . createCTConnectionSite ( ) ) ;
	connection . get ( ) . setAng ( "270" ) ;
	connection . get ( ) . setPos ( DML_FACTORY . createCTAdjPoint2D ( ) ) ;
	connection . get ( ) . getPos ( ) . setX ( "0" ) ;
	//	connection . get ( ) . getPos ( ) . setX ( Long . toString ( BLOCK_WIDTH / 2 ) ) ;
	if ( isTop )
	    {
		connection . get ( ) . setAng ( "270" ) ;
		connection . get ( ) . getPos ( ) . setY ( "0" ) ;
	    }
	else
	    {
		connection . get ( ) . setAng ( "90" ) ;
		connection . get ( ) . getPos ( ) . setY ( Long . toString ( BLOCK_HEIGHT ) ) ;
	    }
	customGeom . getCxnLst ( ) . getCxn ( ) . add ( connection . get ( ) ) ;
    }

    private static void line ( final CTShapeProperties spPr , final STPresetColorVal color )
    {
	spPr . setLn ( DML_FACTORY . createCTLineProperties ( ) ) ;
	spPr . getLn ( ) . setCap ( STLineCap . RND ) ;
	spPr . getLn ( ) . setSolidFill ( DML_FACTORY . createCTSolidColorFillProperties ( ) ) ;
	spPr . getLn ( ) . getSolidFill ( ) . setPrstClr ( DML_FACTORY . createCTPresetColor ( ) ) ; 
	spPr . getLn ( ) . getSolidFill ( ) . getPrstClr ( ) . setVal ( color ) ;
	spPr . getLn ( ) . setMiter ( DML_FACTORY . createCTLineJoinMiterProperties ( ) ) ;
    }

    private static String SAMPLE_SHAPE =                   
	"<p:sp   xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\">"
	+ "<p:nvSpPr>"
	+ "<p:cNvPr id=\"4\" name=\"Title 3\" />"
	+ "<p:cNvSpPr>"
	+ "<a:spLocks noGrp=\"1\" />"
	+ "</p:cNvSpPr>"
	+ "<p:nvPr>"
	+ "<p:ph type=\"title\" />"
	+ "</p:nvPr>"
	+ "</p:nvSpPr>"
	+ "<p:spPr />"
	+ "<p:txBody>"
	+ "<a:bodyPr />"
	+ "<a:lstStyle />"
	+ "<a:p>"
	+ "<a:r>"
	+ "<a:rPr lang=\"en-US\" smtClean=\"0\" />"
	+ "<a:t>Hello World</a:t>"
	+ "</a:r>"
	+ "<a:endParaRPr lang=\"en-US\" />"
	+ "</a:p>"
	+ "</p:txBody>"
	+ "</p:sp>";
}
